import React, { useCallback, useMemo, useRef, useState } from 'react';
interface Props {
  list?: any[];
  containerHeight?: number;
  containerWidth?: number;
  itemHeight?: number;
  ItemBox?: any;
}
const VirtualList: React.FC<Props> = (props) => {
  const { list, containerHeight, ItemBox, itemHeight, containerWidth } = props;
  const containerRef = useRef();
  const [startIndex, setStartIndex] = useState(0);
  const wraperHeight = useMemo(() => {
    return list.length * itemHeight;
  }, [list, itemHeight]);
  const limit = useMemo(() => {
    return Math.ceil(containerHeight / itemHeight);
  }, [startIndex]);
  const endIndex = useMemo(() => {
    return Math.min(startIndex + limit + 2, list.length - 1);
  }, [startIndex, limit]);
  const scrollHandle = useCallback(
    (e) => {
      if (e.target !== containerRef.current) return;
      const scrollTop = e.target.scrollTop;
      let currentIndex = Math.floor(scrollTop / itemHeight);
      if (currentIndex !== startIndex) {
        setStartIndex(currentIndex - 2);
      }
    },
    [containerRef, itemHeight, startIndex],
  );
  const renderList = useCallback(() => {
    const rows = [];
    for (let i = startIndex; i <= endIndex; i++) {
      rows.push(
        <ItemBox
          key={i}
          style={{
            width: '100%',
            height: itemHeight - 1 + 'px',
            borderBottom: '1px solid #aaa',
            position: 'absolute',
            top: i * itemHeight + 'px',
            left: 0,
            right: 0,
          }}
          data={i}
        />,
      );
    }
    return rows;
  }, [startIndex, endIndex, ItemBox]);
  return (
    <div
      ref={containerRef}
      style={{
        height: containerHeight + 'px',
        width: containerWidth + 'px',
        position: 'relative',
        overflow: 'auto',
      }}
      onScroll={scrollHandle}
    >
      <div style={{ height: wraperHeight }}>{renderList()}</div>
    </div>
  );
};
export default VirtualList;
